// 为什么我们要做这个组件  dangerouslySetInnerHTML存在安全风险(主要原因)，我们有三种方法，发现第二种比较中庸也没什么瑕疵
// 这个组件为什么可以当做公共组件  两个以上地方要用到
// 这个组件的作用是什么 安全的将标签渲染

// 解答一下 没啥问题
import React, { useMemo, useState } from 'react'

type SageRenderHtmlProps = {
  htmlContent: string
}

const SafeRenderHtml = ({ htmlContent }: SageRenderHtmlProps) => {
  const [parsedHtml, setParsedHtml] = useState<React.ReactNode[]>([])

  useMemo(() => {
    const createElements = (html: string): React.ReactNode[] => {
      const tempDiv = document.createElement('div')
      tempDiv.innerHTML = html
      const nodes: React.ReactNode[] = []
      for (let i = 0; i < tempDiv.childNodes.length; i++) {
        const node = tempDiv.childNodes[i]
        if (node.nodeType === Node.TEXT_NODE) {
          nodes.push(node.textContent || '')
        } else if (node.nodeType === Node.ELEMENT_NODE) {
          // 特殊处理 img
          if (node.nodeName.toLowerCase() === 'img') {
            const imgProps: React.ImgHTMLAttributes<HTMLImageElement> = {
              src: (node as HTMLImageElement).getAttribute('src') || '',
              alt: (node as HTMLImageElement).getAttribute('alt') || '',
              width: (node as HTMLImageElement).getAttribute('width') ? parseInt((node as HTMLImageElement).getAttribute('width') || '', 10) : undefined,
              height: (node as HTMLImageElement).getAttribute('height') ? parseInt((node as HTMLImageElement).getAttribute('height') || '', 10) : undefined,
            }
            nodes.push(React.createElement('img', imgProps))
          } else if (node.nodeName.toLowerCase() === 'a') {
            const aProps: React.AnchorHTMLAttributes<HTMLAnchorElement> = {
              href: (node as HTMLAnchorElement).getAttribute('href') || '',
              className: (node as HTMLAnchorElement).getAttribute('className') || '',
              target: (node as HTMLAnchorElement).getAttribute('target') || '',
              rel: (node as HTMLAnchorElement).getAttribute('rel') || '',
            }
            nodes.push(React.createElement('a', aProps, ...Array.from(node.childNodes).map(child => createElements(child.textContent || ''))))
          } else {
            // 将 DOM 元素转换为 React 元素
            const element = React.createElement(
              node.nodeName.toLowerCase() as any,
              {},
              ...Array.from(node.childNodes).map(child => createElements(child.textContent || ''))
            )
            nodes.push(element)
          }
        }
      }
      return nodes
    }

    const elements = createElements(htmlContent)
    setParsedHtml(elements)
  }, [htmlContent])

  return (
    <>
      {parsedHtml}
    </>
  )
}

export default SafeRenderHtml


